From integrated EMR sensors to USB- and Bluetooth-connected tablets, Wacom hardware is used with an ever-increasing number of Android devices. While Android was limited to only reporting basic stylus data in the past, there has been significant work in recent releases to improve the richness of the pen experience.
This document provides an overview of framework that exists in Android to support pen input, and is intended to serve as a guide for manufacturers and modders of Android devices.
Kernel Devices
The Linux kernel provides the foundation upon which the Android OS is built. Specialized Wacom drivers provide support for the digitizers themselves, setting them up and exporting their properties to sysfs for use by the Android framework.
As with other Linux systems, a userspace daemon is responsible for managing
devfs. In Android’s case, this daemon is ueventd
. As hardware comes and
goes, device nodes are created under the /dev/input
directory. This
directory is home to input devices of all types: touchscreens, accelerometers,
etc.
Android Input Service
The raw kernel evdev devices are managed by Android’s input service.
This service acts as the userspace input driver, transforming events
to a form consistent with what is defined in the Android API. The
service is powered by an instance of the InputManager
class, which
starts two pipelined event pumps. The first pump cooks raw kernel events
and packages each input packet into a snapshot. The second batches multiple
snapshots into a single event for efficient delivery to apps.
InputReader
Pump
The first pump is an InputReader
, which makes use of the EventHub
to
stay updated on the current state of all known input devices. The event
hub is self-described as "grand central station for events." It keeps
track of devices as they come and go, and can be polled for the latest
list of input events that have appeared from all devices.
Each loop through, the input reader requests a list of all new events from
the event hub. For each event, it locates the associated InputDevice
source and has it perform additional processing. These in turn rely on
a set of "input mappers" for further processing of the events in a form
specific to the device type (e.g. a touchscreen may have its positional
data processed by a TouchInputMapper
, while a mouse would would process
the same data with a CursorInputMapper
).
Generally speaking, the data recieved from the kernel is left in its raw state. The input mappers usually store the value directly, or may provide it to an "accumulator" (e.g. for relative-to-absolute conversion). Sometimes, however, more extensive cooking is necessary — for example, adjusting for the parameters specified in an input device configuration file.
When an input mapper notices that it has recieved a complete event packet
from the kernel, it appends its public state to the end of a queue for
the InputDispatcher
pump to deal with.
InputDispatcher
Pump
The InputDispatcher
pump is run periodically to flush accumulated events
from the InputReader
out to applications. Because of the overhead involved
with notifying apps on every kernel packet, the dispatcher may batch several
rapidly-successive events together for delivery. This preserves intermediate
states without needing to make multiple notifications per screen refresh.
The InputDispatcher
is responsible for more than just relaying events from
hardware: it also handles event injection, ANR warnings, etc.
Framework Features
Configuration
Android provides "Input Device Configuration" files to adjust how the kernel device events are interpreted. For instance, it is possible to tell Android that it should adjust the reported touch size by a given scale factor. It is also possible to use these files to adjust how Android treats the device as a whole: e.g. changing the "deviceType" to a specific type if Android mis-detects it. A complete list of IDC file properties is available for reference.
It should be noted that IDC files cannot be used to specify a calibration
for the toushcreen or EMR sensor. No facility is yet available in Android
to achieve this, though the use of third-party tools such as tslib
and
patches to the InputReader
to apply calibration parameters has been used
as a workaround in the past.
Debugging
Android provides a few different programs that allow you to debug what is going on with input devices at the framework level.
The dmesg
command can be used to determine if the kernel is aware of the
digitizer or not. Log lines prefixed with "input
" should contain both the
name of the input device and a sysfs path. Wacom drivers may produce their
own messages, prefixed with "Wacom".
Android provides the getevent
tool for debugging kernel
devices. This tool can be used to get a list of all known kernel input
devices, view their properties, and even watch the event stream in realtime.
Documentation for the kernel’s input event interface can be found online. See especially the docs for event codes and the multi-touch protocol.
The dumpsys
tool (see here) is able to dump information about
Android services. In particular, the input and window services contain a
wealth of information about the state of Android’s own input driver.